﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 订单收款接口实现
    /// </summary>
    public class OrderCollectionService : BaseService, IOrderCollectionService
    {
        private readonly ILogger<OrderCollectionService> _logger;
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        public OrderCollectionService(IDbContextFactory contentFactory, ILogger<OrderCollectionService> logger,
            IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _logger = logger;
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<OrderCollection?> QueryAsync(Expression<Func<OrderCollection, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = await _context.Set<OrderCollection>()
                .Include(x => x.CollectionRelations).ThenInclude(x=>x.Order)
                .FirstOrDefaultAsync(funcWhere);
            return result;
        }

        /// <summary>
        /// 确认收款
        /// </summary>
        public async Task<bool> ConfirmAsync(string tradeNo, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //检查收款单
            var model = await _context.Set<OrderCollection>()
                .Include(x => x.Payment)
                .Include(x => x.Recharges)
                .Include(x => x.CollectionRelations).ThenInclude(x => x.Order)
                .FirstOrDefaultAsync(x => x.TradeNo == tradeNo);
            if (model == null)
            {
                throw new ResponseException("记录不存在或已删除");
            }
            //如果已经支付则直接返回
            if (model.Status == 2)
            {
                return true;
            }
            //查找会员账户
            var memberModel = await _context.Set<Members>()
                .Include(x => x.Group)
                .FirstOrDefaultAsync(x => x.UserId == model.UserId);
            if (memberModel == null)
            {
                throw new ResponseException("会员账户不存在或已删除");
            }

            //判断收款类型，如果是充值订单
            if (model.TradeType == 1)
            {
                if (model.Recharges.Count == 0)
                {
                    throw new ResponseException("没有找到充值订单，请重试");
                }
                memberModel.Amount += model.PaymentAmount;//增加余额
                //检查有无可升级的会员组
                if (memberModel.Group != null)
                {
                    //条件筛选并排序，返回第一条
                    var upgradeGroupModel = await _context.Set<MemberGroup>().OrderByBatch("-Amount")
                        .FirstOrDefaultAsync(x => x.Id != memberModel.Group.Id && x.IsUpgrade == 1 && x.Amount <= model.PaymentAmount);
                    if (upgradeGroupModel != null && upgradeGroupModel.Amount >= memberModel.Group.Amount)
                    {
                        memberModel.GroupId = upgradeGroupModel.Id;//升级会员组
                    }
                }
                //更改订单状态
                model.Status = 2;
                model.CompleteTime = DateTime.Now;

                //添加消费记录
                await _context.Set<MemberAmountLog>().AddAsync(new MemberAmountLog()
                {
                    UserId = model.UserId,
                    Value = model.PaymentAmount,
                    Remark = $"在线充值，充值交易号:{model.TradeNo}",
                    AddTime = DateTime.Now
                });
                //更新会员
                _context.Set<Members>().Update(memberModel);
                //更新收款单
                _context.Set<OrderCollection>().Update(model);
                //保存到数据库
                return await this.SaveAsync();
            }
            //商品订单
            else
            {
                //如果是余额支付则直接扣款
                if (model.Payment?.PayType == "balance")
                {
                    //检查会员余额是否够扣减
                    if (memberModel.Amount < model.PaymentAmount)
                    {
                        throw new ResponseException("会员账户余额不足本次支付");
                    }
                    memberModel.Amount -= model.PaymentAmount;//扣取余额
                    //修改会员信息
                    _context.Set<Members>().Update(memberModel);
                    //添加消费记录
                    await _context.Set<MemberAmountLog>().AddAsync(new MemberAmountLog()
                    {
                        UserId = memberModel.UserId,
                        Value = model.PaymentAmount * -1,
                        Remark = $"交易单号[{model.TradeNo}]付款",
                        AddTime = DateTime.Now
                    });
                }
                //遍历订单，修改订单支付状态
                foreach(var modelt in model.CollectionRelations)
                {
                    if (modelt.Order != null)
                    {
                        //修改订单的支付状态及支付时间
                        if(model.CollectionType == 2 && modelt.Order.PaymentStatus != 1)
                        {
                            throw new ResponseException("请先支付预付款后再付尾款");
                        }
                        if (model.CollectionType == 1)
                        {
                            modelt.Order.PaymentStatus = 1;
                        }
                        else
                        {
                            modelt.Order.PaymentStatus = 2;
                        }
                        modelt.Order.PaymentTime = DateTime.Now;
                        //如果全部已支付则设置订单为发货状态
                        if(modelt.Order.PaymentStatus == 2)
                        {
                            modelt.Order.Status = 2;
                        }
                        //新增订单日志
                        await _context.Set<OrderLog>().AddAsync(new OrderLog
                        {
                            OrderId = modelt.Order.Id,
                            OrderNo = modelt.Order.OrderNo,
                            ActionType = ActionType.Payment.ToString(),
                            AddBy = await _userService.GetUserNameAsync(),
                            AddTime = model.AddTime,
                            Remark = $"订单[{modelt.Order.OrderNo}]付款{model.PaymentAmount}元"
                        });
                    }
                }
                //修改收款单状态
                model.Status = 2;
                model.CompleteTime = DateTime.Now;
                _context.Set<OrderCollection>().Update(model);
                //保存到数据库
                return await this.SaveAsync();
            }
        }

        /// <summary>
        /// 取消收款
        /// </summary>
        public async Task<bool> CancelAsync(Expression<Func<OrderCollection, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //检查收款单
            var model = await _context.Set<OrderCollection>()
                .Include(x => x.CollectionRelations)
                .FirstOrDefaultAsync(funcWhere);
            if (model == null)
            {
                throw new ResponseException("交易记录不存在或已删除");
            }
            //如果已经付款或取消
            if (model.Status == 2)
            {
                throw new ResponseException("交易已经付款，无法进行取消");
            }
            if(model.Status == 3)
            {
                throw new ResponseException("交易已经取消，无法重复操作");
            }
            //判断收款类型，如果是商品订单
            if (model.TradeType == 0)
            {
                //查询订单列表
                var orderIds = model.CollectionRelations.Select(x => x.OrderId);
                var orderList = await _context.Set<Orders>()
                    .Include(x => x.OrderGoods)
                    .Where(x => orderIds.Contains(x.Id)).ToListAsync();
                //检查订单是否已部分付款
                var payOrderList = orderList.Where(x => x.PaymentStatus > 0);
                if (payOrderList.Count() > 0)
                {
                    throw new ResponseException("部分订单已经付款，无法取消");
                }
                //遍历订单，修改订单状态
                foreach (var order in orderList)
                {
                    //查询货品列表
                    var productIds = order.OrderGoods.Select(x => x.ProductId);//货品列表
                    var productList = await _context.Set<ShopGoodsProduct>()
                        .Include(x => x.ShopGoods)
                        .Where(x => (x.ShopGoods != null && x.ShopGoods.Status == 0) && productIds.Contains(x.Id)).ToListAsync();
                    //遍历货品，返还库存
                    foreach (var modelt in productList)
                    {
                        if (modelt.ShopGoods == null)
                        {
                            continue;
                        }
                        //取得货品的购买数量
                        var orderGoods = order.OrderGoods.FirstOrDefault(x => x.ProductId == modelt.Id);
                        if (orderGoods != null)
                        {
                            //货品及商品减库存，销售减少
                            modelt.StockQuantity += orderGoods.Quantity;
                            modelt.ShopGoods.StockQuantity += orderGoods.Quantity;
                            modelt.ShopGoods.SaleCount = modelt.ShopGoods.SaleCount - orderGoods.Quantity;
                        }
                    }
                    //修改货口及商品数量
                    _context.Set<ShopGoodsProduct>().UpdateRange(productList);
                    //修改订单状态
                    order.Status = 6;
                }
                //批量修改订单
                _context.Set<Orders>().UpdateRange(orderList);
            }
            //修改收款状态
            model.Status = 3;
            model.CompleteTime = DateTime.Now;
            _context.Set<OrderCollection>().Update(model);
            //保存到数据库
            return await this.SaveAsync();
        }

        /// <summary>
        /// 取消收款(计划任务)
        /// </summary>
        public async Task JobCancelAsync(WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //检查收款单
            var list = await _context.Set<OrderCollection>()
                .Include(x => x.CollectionRelations)
                .Where(x => x.Status == 1 && DateTime.Compare(x.EndTime, DateTime.Now) < 0)
                .ToListAsync();
            if (list == null || list.Count == 0)
            {
                return;
            }
            //循环处理
            foreach(var model in list)
            {
                //判断收款类型，如果是商品订单
                if (model.TradeType == 0)
                {
                    //如果是货到付款则不处理
                    if (model.PaymentCash == 1)
                    {
                        continue;
                    }
                    //查询订单列表
                    var orderIds = model.CollectionRelations.Select(x => x.OrderId);
                    var orderList = await _context.Set<Orders>()
                        .Include(x => x.OrderGoods)
                        .Where(x => orderIds.Contains(x.Id)).ToListAsync();
                    //检查订单是否已部分付款
                    var payOrderList = orderList.Where(x => x.PaymentStatus > 0);
                    if (payOrderList.Count() > 0)
                    {
                        continue;
                    }
                    //遍历订单，修改订单状态
                    foreach (var order in orderList)
                    {
                        //查询货品列表
                        var productIds = order.OrderGoods.Select(x => x.ProductId);//货品列表
                        var productList = await _context.Set<ShopGoodsProduct>()
                            .Include(x => x.ShopGoods)
                            .Where(x => (x.ShopGoods != null && x.ShopGoods.Status == 0) && productIds.Contains(x.Id)).ToListAsync();
                        //遍历货品，返还库存
                        foreach (var modelt in productList)
                        {
                            if (modelt.ShopGoods == null)
                            {
                                continue;
                            }
                            //取得货品的购买数量
                            var orderGoods = order.OrderGoods.FirstOrDefault(x => x.ProductId == modelt.Id);
                            if (orderGoods != null)
                            {
                                //货品及商品减库存，销售减少
                                modelt.StockQuantity += orderGoods.Quantity;
                                modelt.ShopGoods.StockQuantity += orderGoods.Quantity;
                                modelt.ShopGoods.SaleCount = modelt.ShopGoods.SaleCount - orderGoods.Quantity;
                            }
                        }
                        //修改货口及商品数量
                        _context.Set<ShopGoodsProduct>().UpdateRange(productList);
                        //修改订单状态
                        order.Status = 6;
                    }
                    //批量修改订单
                    _context.Set<Orders>().UpdateRange(orderList);
                }
                //修改收款状态
                model.Status = 3;
                model.CompleteTime = DateTime.Now;
                _context.Set<OrderCollection>().Update(model);
                //记录日志到文件
                _logger.LogInformation($"定时任务：取消收款单，交易号：{model.TradeNo}，时间：{DateTime.Now}");
            }
            //保存到数据库
            var result = await this.SaveAsync();
            //记录日志到文件
            if (result)
            {
                _logger.LogInformation($"--------------------以上任务执行成功------------------------");
            }
            else
            {
                _logger.LogInformation($"--------------------以上任务执行失败------------------------");
            }
        }

        /// <summary>
        /// 根据条件删除记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<OrderCollection, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var list = await _context.Set<OrderCollection>()
                .Include(x => x.Recharges)
                .Include(x => x.CollectionRelations)
                .Where(funcWhere).ToListAsync();
            if (list == null)
            {
                return false;
            }
            foreach (var modelt in list)
            {
                _context.Set<OrderCollection>().Attach(modelt);
            }
            _context.Set<OrderCollection>().RemoveRange(list);
            return await this.SaveAsync();
        }

        /// <summary>
        /// 修改支付方式(客户)
        /// </summary>
        public async Task<bool> PayAsync(OrderCollectionPaymentDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            //获取当前登录用户
            var userId = await _userService.GetUserIdAsync();
            //根据ID获取记录
            var model = await _context.Set<OrderCollection>()
                .FirstOrDefaultAsync(x => x.Id == modelDto.Id && x.UserId == userId
                    && DateTime.Compare(x.StartTime, DateTime.Now) <= 0 
                    && DateTime.Compare(x.EndTime, DateTime.Now) >= 0);
            //如果不存在则抛出异常
            if (model == null)
            {
                throw new ResponseException("交易单号有误或已失效");
            }
            //判断支付方式是否改变
            if (model.PaymentId == modelDto.PaymentId)
            {
                return true;
            }
            //判断是否已支付
            if (model.Status != 1)
            {
                throw new ResponseException("无法修改交易单支付方式");
            }
            //查询支付方式
            var paymentModel = await _context.Set<Payment>().FirstOrDefaultAsync(x => x.Id == modelDto.PaymentId);
            if (paymentModel == null)
            {
                throw new ResponseException("支付方式有误，请确认后操作");
            }
            //再次支付不允许线下支付
            if (paymentModel.ProviderType == 0)
            {
                throw new ResponseException("交易无法更换线下支付，请重试");
            }
            model.PaymentId = paymentModel.Id;
            model.PaymentTitle = paymentModel.Title;
            _context.Set<OrderCollection>().Update(model);
            //保存到数据库
            return await this.SaveAsync();
        }
    }
}
